#include "pch.h"
#include "Game.h"
#include "PlayGameState.h"
#include "MenuGameState.h"

using namespace std;
using namespace GameStates;

namespace Core
{

    Game game;
    
    ///
    /// Starts the game, runs it and finishes
    ///
    void Game::Run()
    {
        screenWidth = 1024;
        screenHeight = 768;
        fullscreen = false;
        
        running = true; //turns true when game ends.  Is the base of our game loop.

        // Start HGE
        hge = hgeCreate(HGE_VERSION);
        hge->System_SetState(HGE_FRAMEFUNC, GameLoop);
        hge->System_SetState(HGE_WINDOWED, !fullscreen);
        hge->System_SetState(HGE_SCREENWIDTH, screenWidth);
        hge->System_SetState(HGE_SCREENHEIGHT, screenHeight);
        hge->System_SetState(HGE_TITLE, "Bouncing Balls");
        hge->System_SetState(HGE_USESOUND, true);
        hge->System_SetState(HGE_SHOWSPLASH, false);
        hge->System_SetState(HGE_LOGFILE, "hgelog.txt");
        hge->System_SetState(HGE_FPS, 60);
        hge->System_SetState(HGE_FOCUSGAINFUNC, &GainFocus);
        hge->System_SetState(HGE_FOCUSLOSTFUNC, &LoseFocus);

        lostTicks = 0;
        lostTicksStart = 0;
        
        if(hge->System_Initiate())
        {
			resourceManager = new hgeResourceManager("resources.txt");
			
			PushState(new MenuGameState(game));

            hge->System_Start();
            delete resourceManager;
        }
		else
			MessageBox(NULL, hge->System_GetErrorMessage(), "HGE failed to initialize", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
    
        hge->System_Shutdown();
        hge->Release();
    }

    
    ///
    /// The game's main loop
    ///
    bool GameLoop()
    {
        game.hge->Gfx_BeginScene();
        game.hge->Gfx_Clear(0xFFAAAAAA);
        
        // Quit if there are no states on the stack
        if(game.stateStack.size() == 0)
            return true;
        
        // Update the top-most state
        if((*(game.stateStack.end()-1))->Update() == false)
            game.PopState(); 
        
        game.hge->Gfx_EndScene();
        
        return !game.running;
    }
    
    ///
    /// Adds a state to the top of the stack and calls its Start method
    ///
    void Game::PushState(GameState *state)
    {
        stateStack.push_back(state);
        state->Start();
    }
    
    ///
    /// Removes the top-most state from the stack
    ///
    void Game::PopState()
    {
        if(stateStack.size() > 0)
        {
            vector<GameState*>::iterator lastState = stateStack.end()-1;
            (*lastState)->End();
            delete (*lastState);
            stateStack.pop_back();
        }
    }
    
    bool Game::GainFocus()
    {
        game.lostTicks += game.GetGameTickCount() - game.lostTicksStart;
        return false;
    }

    bool Game::LoseFocus()
    {
        game.lostTicksStart = game.GetGameTickCount();
        return false;
    }

    unsigned int Game::GetGameTickCount()
    {
        return GetTickCount() - lostTicks;
    }

}
